<?php

namespace app\admin\controller\facrm;


use app\common\controller\Backend;
use fast\Random;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\exception\ValidateException;
use think\Queue;


/**
 * 发票管理
 */
class Invoice extends Backend
{

    protected $model = null;
    /**
     * 快速搜索时执行查找的字段
     */
    protected $searchFields = 'invoice_name';
    protected $childrenAdminIds = [];
    protected $noNeedRight = ['selectpage', 'history'];
    protected $tpl_key = "invoice_tpl";

    public function _initialize()
    {
        parent::_initialize();
        $this->model = model('\app\admin\model\facrm\Invoice');
        $this->request->filter(['strip_tags']);
        $this->assignconfig('admin_id', $this->auth->id);
    }

    /**
     * 我申请的发票
     */
    public function index($scene_list = array())
    {

        //设置过滤方法
        $this->request->filter(['strip_tags']);
        $scene_list = $scene_list ? $scene_list : ['owner' => '我申', 'branch' => '下属'];
        $customer_id = $this->request->param("customer_id");
        if ($this->request->isAjax()) {
            $filter_w = $this->getFilterWhere($scene_list);

            if ($customer_id) {
                $filter_w['customer_id'] = $customer_id;
            }


            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                $this->request->request(['custom' => $filter_w]);
                return $this->selectpage();
            }

            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $total = $this->model
                ->where($where)
                ->where($filter_w)
                ->with([
                ])
                ->order($sort, $order)->fetchSql(false)
                ->count();
            $list = $this->model
                ->where($where)
                ->where($filter_w)
                ->with([
                    'createUser' => function ($user) {
                        $user->field('id,username,nickname');
                    },
                    'contract' => function ($user) {
                        $user->field('id,name,number');
                    },
                    'customer' => function ($customer) {
                        $customer->field('id,name');
                    },
                ])
                ->order($sort, $order)
                ->limit($offset, $limit)->fetchSql(false)
                ->select();
            $result = array("total" => $total, "rows" => $list);

            return json($result);
        }

        $this->view->assign("scene_list", $scene_list);
        return $this->view->fetch('index');
    }


    /**
     * 全部发票
     */
    public function lists()
    {
        $this->view->assign("action", 'lists');
        return $this->index(['all' => '全部发票']);
    }

    /**
     * 发票配置
     */
    public function setting()
    {
        $this->model = new \app\admin\model\facrm\Setting();
        $row = $this->model->where('key', $this->tpl_key)->find();

        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");

            if ($params) {
                $params['key'] = $this->tpl_key;
                $params['describe'] = "发票配置";
                $result = false;
                Db::startTrans();
                try {

                    if (!$row) {
                        //添加
                        $result = $this->model->allowField(true)->save($params);
                    } else {
                        //修改
                        $result = $row->allowField(true)->save($params);
                    }

                    Db::commit();
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }

        $this->view->assign("row", $row);
        $this->view->assign("key", $this->tpl_key);
        return $this->view->fetch();
    }

    /**
     * 申请发票
     * @return mixed
     */
    public function add()
    {

        $flow = model('\app\admin\model\facrm\Flow');
        $flow_r = \app\admin\model\facrm\Flow::getFlow($this->auth->id, 'invoice');

        if (!$flow_r) $this->error(__('审批配置不存在，请先配置'), url("facrm/flow/index"));
        //获取发票配置
        $settingModel = new \app\admin\model\facrm\Setting();
        $setting = $settingModel->where('key', $this->tpl_key)->where('status', 1)->value('values');
        if (!$setting) {
            $this->error(__('发票开具申请未开启'));
        }

        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if (!isset($params['contract_id']))
                $this->error(__('请选择合同'));


            $contractModel = new \app\admin\model\facrm\Contract();
            //获取合同情况
            $contract_r = $contractModel->get($params['contract_id']);
            if (!$contract_r)
                $this->error(__('没有找到合同'));


            if ($contract_r['check_status'] != 2)
                $this->error(__('合同未通过审核不能申请发票'));


            if ($this->model->where('contract_id', $contract_r['id'])->where(function ($query) {
                $query->where('check_status', 'in', [0, 1])->whereOr('status', 'in', [0, 1]);
            })->count()) {
                $this->error(__("该合同还有未审批或未开票的申请"));
            }
            //判断开票金额,不能大于合同金额且不能大于回款金额
            $money = bcadd($params['money'], $contract_r['invoice_money'], 2);

            if ($money > $contract_r['money'] && $money > $contract_r['return_money']) {
                $this->error(__("累计开票金额,不能大于合同金额且不能大于回款金额"));
            }

            $params = array_merge($params, [
                'create_admin_id' => $this->auth->id,
                'invoice_admin_id' => 0,
                'customer_id' => $contract_r['customer_id'],
                'status' => 0,
                'check_status' => 0,
            ]);

            $result = false;
            $invoice_id = 0;
            Db::startTrans();
            try {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $this->model->validateFailException(true)->validate($name . '.add');
                $result = $this->model->allowField(true)->save($params);
                $invoice_id = $this->model->id;
                Db::commit();
            } catch (ValidateException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($result !== false) {
                //处理合同审核流程
                $flow->addFlow($invoice_id, $this->auth->id, 'invoice', $flow_r);
                hook("facrm_invoice_add", array_merge($params, ['id' => $invoice_id]));
                $this->success();
            } else {
                $this->error(__('No rows were inserted'));
            }
        }


        $setting = json_decode($setting, true);

        $this->view->assign("flow", $flow_r);
        $this->view->assign("invoice_set", $setting);
        $this->assignconfig("invoice_set", $setting);

        return $this->view->fetch('add', ['addtype' => 'add']);
    }

    /**
     * 获取客户历史发票资料
     * @Internal
     * @return mixed
     */
    public function history($customer_id = NULL)
    {
        if (!$this->auth->check('facrm/invoice/add')) {
            $this->error(__('You have no permission'), '');
        }
        if (!$customer_id) {
            $this->error(__('No Results were found'));
        }
        $invoice = $this->model->where('customer_id', $customer_id)->orderRaw("field(check_status,'2','1','0','3')")->order('id desc')->fetchSql(false)->find();

        if (!$invoice) {
            $this->error(__('No Results were found'));
        }
        $invoice->hidden(['files']);
        $this->success('', '', $invoice);

    }


    /**
     * 修改
     * @param null $ids
     */
    public function edit($ids = NULL)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }

        $flow = model('\app\admin\model\facrm\Flow');

        if ($row->flow_id) {
            $flow->where('id', $row->flow_id);//处理流程被删除
        }

        $flow_r = $flow->where('types', 'invoice')->where("status", 1)->find();
        if ($this->request->isPost()) {

            $params = $this->request->post("row/a");
            if ($params) {
                if ($row->check_status == 2) {
                    //审核通过的只能修改负责人和备注、处理情况、续费单价
                    $params_update = array();
                    isset($params['remarks']) ? $params_update['remarks'] = $params['remarks'] : '';
                    $result = $row->allowField(true)->save($params_update);
                    return $this->success();
                }
                /* elseif ($row->check_status == 1) {
                    //审核中的不能修改
                    return $this->error(__("审核中的不能修改,请先驳回再修改"));
                }*/
                $params['check_status'] = 0;//重新改成待审核状态

                //获取合同情况
                $contract_r = $row->contract;
                if (!$contract_r)
                    $this->error(__('没有找到合同'));


                if ($contract_r['check_status'] != 2)
                    $this->error(__('合同未通过审核不能申请发票'));

                //判断开票金额,不能大于合同金额且不能大于回款金额
                $money = bcadd($params['money'], $contract_r['invoice_money'], 2);

                if ($money > $contract_r['money'] && $money > $contract_r['return_money']) {
                    $this->error(__("累计开票金额,不能大于合同金额且不能大于回款金额"));
                }


                $result = false;
                Db::startTrans();
                try {
                    //是否采用模型验证
                    $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    $row->validateFailException(true)->validate($name . '.edit');
                    $invoice_id = $row->id;
                    $result = $row->allowField(true)->save($params);
                    if ($result) {

                    }
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    //处理合同审核流程
                    $flow->addFlow($invoice_id, $this->auth->id, 'invoice', $flow_r);
                    hook("facrm_invoice_edit", array_merge($params, ['id' => $invoice_id]));
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $this->view->assign("row", $row);
        $this->view->assign("flow", $flow_r);
        return $this->view->fetch('', ['addtype' => 'add']);

    }

    /**
     * 开具
     */
    public function opener($ids = NULL)
    {
        //其实就是把发票附件上传
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        if ($row->status == 2) {
            $this->error(__('已开具，不能重复开具'));
        }
        if ($this->request->isPost()) {

            $params = $this->request->post("row/a");
            if ($params) {
                $params['status'] = 2;
                $result = $row->allowField(true)->save($params);

                if ($result) {
                    $row->contract()->setInc('invoice_money', $row->money);
                    //钩子
                    hook("facrm_invoice_opener", array_merge($row->toArray(), $params));
                    return $this->success();
                }


            }
            $this->error(__('No rows were updated'));
        }
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }


    /**
     * 删除
     * @param string $ids
     */
    public function del($ids = "")
    {
        if (!$this->request->isPost()) {
            $this->error(__("Invalid parameters"));
        }
        $ids = $ids ? $ids : $this->request->post("ids");
        if ($ids) {
            $pk = $this->model->getPk();
            $this->childrenAdminIds = $this->auth->getChildrenAdminIds(true);
            $list = $this->model->where($pk, 'in', $ids)->where('create_admin_id', 'in', $this->childrenAdminIds)->select();

            $count = 0;
            Db::startTrans();
            try {
                foreach ($list as $k => $v) {
                    $count += $v->delete();
                }
                Db::commit();
            } catch (PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if ($count) {
                $this->success();
            } else {
                $this->error(__('No rows were deleted'));
            }
        }
        $this->error(__('Parameter %s can not be empty', 'ids'));
    }


    /**
     * 处理过滤where条件
     * @return array
     */
    private function getFilterWhere($scene_list)
    {
        $filter = $this->request->get("filter", '');
        $filter = (array)json_decode($filter, true);
        $filter_w = [];
        $filter['scene_id'] = isset($filter['scene_id']) ? $filter['scene_id'] : 1;
        if (isset($filter['scene_id'])) {

            if (!isset($scene_list[$filter['scene_id']])) {
                $this->error(__("您没有权限"));
            }
            switch ($filter['scene_id']) {
                case 'all':
                    //全部
                    break;
                case 'owner':
                    //我的
                    $filter_w['create_admin_id'] = $this->auth->id;
                    break;
                case 'branch':
                    //下级
                    $this->childrenAdminIds = $this->auth->getChildrenAdminIds(false);
                    $filter_w['create_admin_id'] = ['in', $this->childrenAdminIds];
                    break;
                default://其它的未做 TODO
                    $filter_w['create_admin_id'] = $this->auth->id;
            }
            unset($filter['scene_id']);
            $this->request->get(['filter' => json_encode($filter)]);
        }
        return $filter_w;
    }


}
